package graph.paint.gui;

import graph.Graph;
import graph.TextGraphBuilder;
import graph.algorithm.Multiplyer;
import graph.algorithm.Rotator;
import graph.layout.AutoLayout;
import graph.layout.CenterLayout;
import graph.layout.FlattenLayout;
import graph.layout.GridLayout;
import graph.layout.RandomLayout;
import graph.layout.ShakeLayout;
import graph.paint.GraphPainter;
import graph.paint.ViewPort;
import graph.paint.text.TextPainter;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class PaintGraph {
	static String[] graphs = {
		"a-b-c-d,c-e-f,g-e-h,i-j-h,k-j-l-m,l-n-o-p,l-q-r-l,s-r-t,r-u,q-v-w-x,w-y",
		"",
		"abba-boboo",
		"abba-boboo-cafe-dodo-elfenben-fobi-gnav-holekleiv,dodo-abba-holekleiv-elfenben,cafe-fobi,boboo-gnav",
		"0-1-2-0-3-4-0-5-6-0-7-8-0-9-8-80-90-9-1-10-20-2-3-30-40-4-5-50-60-6-7-70-80,10-90,20-30,40-50,60-70",
	};
	static int index=4;
	static ViewPort viewPort = new ViewPort(-100,100,-100,100);
	static Graph<String,Object> graph = buildGraph();
	static Display display;
	static Shell shell;
	static TextPainter textPainter = new TextPainter(12, SWT.COLOR_GRAY);
	static GraphPainter<String,Object> painter = new GraphPainter<String,Object>(viewPort, textPainter, textPainter);
	static AutoLayout autoLayout = new AutoLayout();
	static CenterLayout centerLayout = new CenterLayout();
	public static void main(String[] args) {
		display = new Display();
		shell = new Shell(display);
		shell.addPaintListener(new PaintListener() {
			public void paintControl(PaintEvent event) {
				Rectangle rect = shell.getClientArea();
				painter.setArea(rect);
				painter.paint(graph, event.gc);
			}
		});
		MyMouseListener ml = new MyMouseListener();
		shell.addMouseListener(ml);
		shell.addMouseMoveListener(ml);
		
		shell.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				switch (e.character) {
				case 'a':
					autoLayout.layout(graph, viewPort);
					shell.redraw();
					break;
				case 'c':
					centerLayout.layout(graph, viewPort);
					shell.redraw();
					break;
				case 'f':
					new FlattenLayout().layout(graph, viewPort);
					shell.redraw();
					break;
				case 'g':
					new GridLayout(5).layout(graph, viewPort);
					shell.redraw();
					break;
				case 's':
					new ShakeLayout().layout(graph, viewPort);
					shell.redraw();
					break;
				case '-':
					autoLayout.zoomOut();
					autoLayout.layout(graph, viewPort);
					shell.redraw();
					break;
				case '+':
					autoLayout.zoomIn();
					autoLayout.layout(graph, viewPort);
					shell.redraw();
					break;
				case 'p':
					System.out.printf("%s%n", graph);
					break;
				case '2':
				case '3':
				case '4':
				case '5':
				case '6':
				case '7':
				case '8':
				case '9':
					multiply(e.character - '0');
					shell.redraw();
					break;
				}
			}

			private void multiply(int i) {
				Multiplyer m = new Multiplyer(i, false);
				m.transform(graph);
			}
		});
		shell.setBounds(10, 10, 1000, 1000);
		shell.open();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
		display.dispose();
	}

	static Graph<String,Object>  buildGraph() {
		TextGraphBuilder builder = new TextGraphBuilder();
		Graph<String,Object> graph = builder.build(graphs[index]);
		RandomLayout rl = new RandomLayout();
		rl.layout(graph, viewPort);
		return graph;
	}
	static class MyMouseListener implements MouseListener, MouseMoveListener {
		private boolean mouseDown = false;
		int x, y;
		@Override
		public void mouseMove(MouseEvent e) {
			if (!mouseDown) return;
			int dx = e.x - x;
			int dy = e.y - y;
			x = e.x;
			y = e.y;
			Rotator rot = new Rotator(dx, dy);
			rot.transform(graph);
			shell.redraw();
//			System.out.printf("dx:%s dy:%s%n", dx, dy);
		}

		@Override
		public void mouseDoubleClick(MouseEvent arg0) {
		}

		@Override
		public void mouseDown(MouseEvent e) {
			mouseDown = true;
			x = e.x;
			y = e.y;
		}

		@Override
		public void mouseUp(MouseEvent arg0) {
			mouseDown = false;
		}
		
	}
	
}
